package servicios;

import java.net.URI;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import modelo.Cliente;
import modelo.Direccion;
import modelo.Empresa;
import modelo.Factura;
import modelo.Persona;
import modelo.enums.Tarifa;
import modelo.enums.TipoVia;
import persistencia.clientes.BDCliente;
import persistencia.clientes.BDClienteImpl;
import persistencia.facturas.BDFacturaImpl;

import com.sun.jersey.api.client.ClientResponse.Status;

@Path("clientes")
public class ClienteService
{

    private static final BDCliente datos = new BDClienteImpl();

    @Context
    private UriInfo uriInfo;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response devuelveTodosClientes()
    {
        return Response.ok(datos.getAll()).build();
    }

    @Path("{nif}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response devuelveClientePorNIF(@PathParam("nif") String nif)
    {
        Cliente cliente = datos.findByNIF(nif);
        if (cliente == BDCliente.CLIENTE_NULL)
            return Response.status(Status.NOT_FOUND).build();
        return Response.ok(cliente).build();
    }

    @Path("{nif}/facturas")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response devuelveFacturasPorNIF(@PathParam("nif") String nif)
    {
        return Response.ok(FacturaService.datos.findByNif(nif)).build();
    }

    @Path("{nif}/facturas/{id}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response devuelveFacturaPorNIFYCodigo(@PathParam("nif") String nif,
            @PathParam("id") int codigo)
    {
        Factura factura = FacturaService.datos.findByNifAndCode(nif, codigo);
        if (factura == BDFacturaImpl.FACTURA_NULL)
        {
            return Response.status(Status.NOT_FOUND).build();
        }
        else
        {
            return Response.ok(FacturaService.datos.findByNifAndCode(nif, codigo)).build();
        }
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response anyadeCliente(@FormParam("tipo") String tipo, @FormParam("nif") String nif,
            @FormParam("nombre") String nombre, @FormParam("apellidos") String apellidos,
            @FormParam("tarifa") Tarifa tarifa, @FormParam("tipovia") TipoVia tipoVia,
            @FormParam("nombrecalle") String calle, @FormParam("cp") String cp,
            @FormParam("patio") String patio, @FormParam("piso") String piso,
            @FormParam("puerta") String puerta)
    {
        if (datos.findByNIF(nif) == BDClienteImpl.CLIENTE_NULL)
        {
            Direccion direccion = new Direccion(tipoVia, calle, cp, patio, piso, puerta);
            Cliente cliente;
            if (tipo.equalsIgnoreCase("persona"))
                cliente = new Persona(nombre, apellidos, nif, direccion, tarifa);
            else
                cliente = new Empresa(nombre, nif, direccion, tarifa);

            datos.insert(cliente);

            UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder();
            URI uri = uriBuilder.path(nif).build();
            return Response.created(uri).build();
        }
        else
        {
            return Response.status(Status.CONFLICT).build();
        }
    }

    @Path("{nif}")
    @DELETE
    @Produces(MediaType.APPLICATION_JSON)
    public Response borrarCliente(@PathParam("nif") String nif)
    {
        Cliente cliente = datos.findByNIF(nif);
        if (cliente != BDClienteImpl.CLIENTE_NULL)
        {
            FacturaService.datos.delete(nif);
            datos.delete(nif);
            return Response.status(Status.OK).build();
        }
        return Response.status(Status.NOT_FOUND).build();
    }

}